fn main() {
    println!("============================");
    test01_raw_point();
    println!("============================");
    test02_unsafe_fn();
    println!("============================");
    test03_safe_abstruct();
    println!("============================");
    test05_static_var();
    println!("============================");
}

fn test01_raw_point() {
    let mut num = 5;
    let r1 = &raw const num;
    let r2 = &raw mut num;

    let address = 0x012345usize;
    let r = address as *const i32;

    unsafe {
        println!("r1 is: {}", *r1);
        println!("r2 is: {}", *r2);
    }
}

unsafe fn dangerous() {}
fn test02_unsafe_fn() {
    unsafe {
        dangerous();
    }
}

fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = values.len();

    assert!(mid <= len);

    use std::slice;
    let ptr = values.as_mut_ptr();
    unsafe {
        (
            slice::from_raw_parts_mut(ptr, mid),
            slice::from_raw_parts_mut(ptr.add(mid), len - mid),
        )
    }
}
fn test03_safe_abstruct() {
    {
        //unsafe use
        use std::slice;

        let address = 0x01234usize;
        let r = address as *mut i32;

        //let values: &[i32] = unsafe { slice::from_raw_parts_mut(r, 10000) };//segment fault
    }
    {
        let mut str = [1, 2, 3, 4, 5];
        let (x, y) = split_at_mut(&mut str, 3);
        println!("{x:?}");
        println!("{y:?}");
    }
}

unsafe extern "C" {
    fn abs(input: i32) -> i32;
}
unsafe extern "C" {
    safe fn abs_v2(input: i32) -> i32;
}

#[unsafe(no_mangle)]
pub extern "C" fn call_from_c() {
    println!("Just called a Rust function from C!");
}
fn test04_extern() {
    unsafe {
        println!("Absolute value of -3 according to C: {}", abs(-3));
    }
    println!("Absolute value of -3 according to C: {}", abs_v2(-3));
}

static HELLO_WORLD: &str = "Hello, world!";
static mut COUNTER: u32 = 0;

/// SAFETY: 同时在多个线程调用这个方法是未定义的行为，所以你*必须*保证同一时间只
/// 有一个线程在调用它。
unsafe fn add_to_count(inc: u32) {
    unsafe {
        COUNTER += inc;
    }
}
fn test05_static_var() {
    println!("name is: {HELLO_WORLD}");
    unsafe {
        // SAFETY: 它只在 `main` 这一个线程被调用。
        add_to_count(3);
        println!("COUNTER: {}", *(&raw const COUNTER));
    }
}

unsafe trait Foo {
    // 方法在这里
}

unsafe impl Foo for i32 {
    // 方法实现在这里
}
fn test06_unsafe_trait(){

}
